/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.just.dusin.ooii.component.kj;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.dusin.webcoal.exception.OOIIException;

import org.just.dusin.ooii.component.Pipe;
import org.just.dusin.ooii.database.DatabaseConnectionSQL;

import org.just.dusin.ooii.database.RealDeviceBean;
import org.just.dusin.ooii.database.RealDeviceDao;
import org.just.dusin.ooii.database.RealDeviceInfoBean;
import org.just.dusin.ooii.database.RealDeviceInfoDao;
import org.just.dusin.ooii.database.YearPlanBean;
import org.just.dusin.ooii.database.YearPlanDao;
import org.just.dusin.ooii.util.DateUtil;

/**
 *将仪表数据转换成需要的消息
 * @author Administrator
 */
public class KJ215ConverterPipe extends Pipe {
    private static Logger logger = Logger.getLogger(KJ215ConverterPipe.class.getName());
    private RealDeviceBean realDeviceStatus;
    private RealDeviceInfoBean realDeviceData;
    private RealDeviceDao realDeviceStatusDao;
    private RealDeviceInfoDao realDeviceDataDao;
    private YearPlanDao yearPlanDao;
    private String orgCode;
    private String cityName = "a";
    private String countyName = "b";
    private String mineName = "c";
    private int acquistionFrequence = 5; //采集频率，5分钟
    private int id = 0;                      //采集次数
    private int lastMinute = -1;               //上次采集时间 分钟.防止重复采集同一分钟的 数据
    private int rate = 100;
    private int smycValue=2;           // 输煤异常阈值
    private int smycTime= 1;             //输煤异常判断时间，以采集频率5分钟为单位
    private double smycTotalValue=0;      //输煤异常累计量
    private int smycCount=1;             //输煤异常计数
    private byte smyc = 0;
    private int precision = 3;           //精确度，单位吨
    private int factor ;                //计算四舍五入的因子，由precesion决定。如precision=3 ,则factor = 1000;

    public int getPrecision() {
        return precision;
    }

    public void setPrecision(int precision) {
        this.precision = precision;
    }
    
    
    
    public int getSmycTime() {
        return smycTime;
    }

    public void setSmycTime(int smycTime) {
        this.smycTime = smycTime;
    }

    public int getSmycValue() {
        return smycValue;
    }

    public void setSmycValue(int smycValue) {
        this.smycValue = smycValue;
    }
    
    
    private int currentNoDataTimes=0;  //无数据返回次数，发送指令给仪表，仪表连续无数据返回的累计次数
    private int noDataTimes=3;        //设备如3次无数据返回，将发送（通信异常或其他相应异常，如仪表损坏、通信异常等）    
    
//    private RealDeviceBean oldStatus;        //存放上次状态
//    private RealDeviceInfoBean oldDeviceInfo;  //存放上次设备数据
    private DatabaseConnectionSQL dc;

    public KJ215ConverterPipe() {
//        oldStatus = new RealDeviceBean();
//        oldDeviceInfo=new RealDeviceInfoBean();
        factor = (int)Math.pow(10, precision);
    }

    public String getCityName() {
        return cityName;
    }

    public void setCityName(String cityName) {
        this.cityName = cityName;
    }

    public String getCountyName() {
        return countyName;
    }

    public void setCountyName(String countyName) {
        this.countyName = countyName;
    }

    public DatabaseConnectionSQL getDc() {
        return dc;
    }

    public void setDc(DatabaseConnectionSQL dc) {
        this.dc = dc;
    }

    public String getMineName() {
        return mineName;
    }

    public void setMineName(String mineName) {
        this.mineName = mineName;
    }

    public String getOrgCode() {
        return orgCode;
    }

    public void setOrgCode(String orgCode) {
        this.orgCode = orgCode;
    }

    public int getRate() {
        return rate;
    }

    public void setRate(int rate) {
        this.rate = rate;
    }

    @Override
    public void process(String msg) throws OOIIException {
        try {
            realDeviceStatusDao = new RealDeviceDao(dc.getConnection());
            realDeviceDataDao = new RealDeviceInfoDao(dc.getConnection());
            yearPlanDao = new YearPlanDao(dc.getConnection());
            //取出标准就数据            

            String[] msgs = createMsgs(msg);
            if (msgs != null) {
                for (String m : msgs) {
                    sink.process(m);
                }
            }
            logger.info("处理完消息"+msg);
        } catch (Exception e) {
            e.printStackTrace();
            throw (new OOIIException(e));
        } finally {
            dc.close();
        }
    }

    @Override
    public void process(List<String> msgs) throws OOIIException {
        for (String msg : msgs) {
            process(msg);
        }
    }

//    private void updateDeviceStatus(String status) throws Exception{
//        realDeviceData = realDeviceDataDao.findByOrgCode(orgCode);
//        
//    }
//    
    private String[] createMsgs(String msg) throws Exception {
        String[] msgs = null;
        List<String> msgList = new ArrayList<String>();

        Map map = DataPackage.depackYBSJ(msg);
        double currentTotal = (Double) map.get("currentTotal");
        double flowSpeed = (Double) map.get("flowSpeed");
        double beltSpeed = (Double) map.get("beltSpeed");
        byte shellOpen = (Byte) map.get("shellOpen");
        int type = (Integer) map.get("type");
        int no = (Integer) map.get("no");
        Date now = (Date)map.get("time");
        String time = DateUtil.get(now);
         
        if(type==0){   //有正常数据            
            realDeviceData = realDeviceDataDao.findByOrgCode(orgCode);
            currentNoDataTimes = 0;
            if (realDeviceData == null) {
                realDeviceData = new RealDeviceInfoBean();
                realDeviceData.setOrgcode(orgCode);
                realDeviceData.setBeltspeed(beltSpeed);
                realDeviceData.setCurrenttotal(currentTotal);
                realDeviceData.setFlowspeed(flowSpeed);
                //realDeviceData.set;      //realDeviceData中可考虑添加设备号; 可考虑增加上个整5分钟的仪表累计数，可能提高一定的容错性
                realDeviceData.setCurrenthourout(0);
                realDeviceData.setInitialvalueofhour(currentTotal);
                realDeviceData.setLasttotal(currentTotal);
                realDeviceData.setTime(time);
                realDeviceDataDao.doCreate(realDeviceData);
            } else {
                realDeviceData.setBeltspeed(beltSpeed);
                realDeviceData.setCurrenttotal(currentTotal);
                realDeviceData.setFlowspeed(flowSpeed);
                double drate=1;
                int nowMinute = now.getMinutes();
                if (nowMinute != lastMinute && nowMinute % acquistionFrequence == 0) {
                    id++;
                    lastMinute = nowMinute;  //防止重复采集
                    double output = currentTotal - realDeviceData.getLasttotal(); 
                    
                   
                    
                    YearPlanBean yearPlanBean = yearPlanDao.findByOrgCode_Year(orgCode, now.getYear()+1900);
                    if(yearPlanBean!=null){
                        rate = (int)yearPlanBean.getRate();
                    }
                    drate = rate/100.0;
                    output = output*drate;
                    output = (int)(output*factor+0.5); //四舍五入
                    output = output/factor;
                    if(output<0) output =0;      //负产量归零
                    String dataMsg = DataPackage.packCLSC(id, cityName, countyName, mineName, time, "t", output, rate);
                    msgList.add(dataMsg);
                    if (nowMinute == 0) {//小时数据开始
                        realDeviceData.setInitialvalueofhour(currentTotal);                    
                    } 
                    realDeviceData.setLasttotal(currentTotal);      
                    
                    smycTotalValue+=output;
                    smycCount++;
                    if(output>smycValue){
                        smyc = 0;
                    }else{
                        if(smycCount%smycTime==0){    
                            if(smycTotalValue<smycValue){   //规定时间内输煤小于指定值，输煤异常
                                smyc = 1;
                            }         
                            else {
                                smyc = 0;
                            }
                            smycTotalValue = 0;
                            smycCount=0;
                        }
                    }
                }
                
                realDeviceData.setCurrenthourout((currentTotal- realDeviceData.getInitialvalueofhour())*drate);
                realDeviceData.setTime(time);
                realDeviceDataDao.doUpdate(realDeviceData);
            }
            byte txyc = (byte) 0;  //判断异常
            byte jlyc;

            if (Math.abs(beltSpeed)<0.00001&& flowSpeed > 1) //计量仪器有产量输出，但监测到输煤设备为停止状态；输煤重量小于20，报计量异常
            {
                jlyc = (byte) 1;
            } else {
                jlyc = (byte) 0;
            }
            byte wkyc = (byte) (1 - shellOpen);
            byte sbzt=0;
            if(Math.abs(beltSpeed)<0.00001){   //设备停止
                sbzt=1;
            }
            byte gdyc=0;
            
            realDeviceStatus = realDeviceStatusDao.findByOrgCode(orgCode); //读取数据库数据

            if (realDeviceStatus == null) {  //不存在创建

                realDeviceStatus = new RealDeviceBean();

                realDeviceStatus.setWkyc(shellOpen);
                realDeviceStatus.setJlyc(jlyc);
                realDeviceStatus.setSmyc(smyc);
                realDeviceStatus.setTxyc(txyc);
                realDeviceStatus.setDeviceNo("1");
                realDeviceStatus.setTime(time);
                realDeviceStatus.setOrgCode(orgCode);
                realDeviceStatusDao.doCreate(realDeviceStatus);
            } else {
                //状态发生改变，则产生异常消息    
                if (realDeviceStatus.getJlyc() != jlyc || realDeviceStatus.getSmyc() != smyc || realDeviceStatus.getWkyc() != wkyc || realDeviceStatus.getTxyc() != txyc||realDeviceStatus.getSbzt()!=sbzt||realDeviceStatus.getGdyc()!=gdyc) {
                    String status = "" + smyc + jlyc + wkyc + txyc+sbzt+gdyc;
                    String ycMsg = DataPackage.packCLYC(0, cityName, countyName, mineName, time, status);
                    msgList.add(ycMsg);
                    realDeviceStatusDao.updateYCStatus(status, orgCode, now);
                }
            }            
        }else if(type==1){  //设备无数据回应
            currentNoDataTimes++;
            smyc = 2;
            byte jlyc = 2;
            byte wkyc = 2;
            byte txyc = 1;
            byte sbzt = 2;
            byte gdyc = 1;
                
            realDeviceStatus = realDeviceStatusDao.findByOrgCode(orgCode); //读取数据库数据

            if (realDeviceStatus == null) {  //不存在创建

                realDeviceStatus = new RealDeviceBean();

                realDeviceStatus.setWkyc(shellOpen);
                realDeviceStatus.setJlyc(jlyc);
                realDeviceStatus.setSmyc(smyc);
                realDeviceStatus.setTxyc(txyc);
                realDeviceStatus.setDeviceNo("1");
                realDeviceStatus.setTime(time);
                realDeviceStatus.setOrgCode(orgCode);
                realDeviceStatusDao.doCreate(realDeviceStatus);
            } else {
                //状态发生改变，则产生异常消息    
                if (realDeviceStatus.getJlyc() != jlyc || realDeviceStatus.getSmyc() != smyc || realDeviceStatus.getWkyc() != wkyc || realDeviceStatus.getTxyc() != txyc||realDeviceStatus.getSbzt()!=sbzt||realDeviceStatus.getGdyc()!=gdyc) {
                    String status = "" + smyc + jlyc + wkyc + txyc+sbzt+gdyc;
                    String ycMsg = DataPackage.packCLYC(0, cityName, countyName, mineName, time, status);
                    msgList.add(ycMsg);
                    realDeviceStatusDao.updateYCStatus(status, orgCode, now);
                }
            }                
        }else if(type==2){   //异常数据
            smyc = 2;
            byte jlyc = 2;
            byte wkyc = 2;
            byte txyc = 1;
            byte sbzt = 2;
            byte gdyc = 0;
                
            realDeviceStatus = realDeviceStatusDao.findByOrgCode(orgCode); //读取数据库数据
            if (realDeviceStatus == null) {  //不存在创建
                realDeviceStatus = new RealDeviceBean();
                realDeviceStatus.setWkyc(shellOpen);
                realDeviceStatus.setJlyc(jlyc);
                realDeviceStatus.setSmyc(smyc);
                realDeviceStatus.setTxyc(txyc);
                realDeviceStatus.setDeviceNo("1");
                realDeviceStatus.setTime(time);
                realDeviceStatus.setOrgCode(orgCode);
                realDeviceStatusDao.doCreate(realDeviceStatus);
            } else {
                //状态发生改变，则产生异常消息    
                if (realDeviceStatus.getJlyc() != jlyc || realDeviceStatus.getSmyc() != smyc || realDeviceStatus.getWkyc() != wkyc || realDeviceStatus.getTxyc() != txyc||realDeviceStatus.getSbzt()!=sbzt||realDeviceStatus.getGdyc()!=gdyc) {
                    String status = "" + smyc + jlyc + wkyc + txyc+sbzt+gdyc;
                    String ycMsg = DataPackage.packCLYC(0, cityName, countyName, mineName, time, status);
                    msgList.add(ycMsg);
                    realDeviceStatusDao.updateYCStatus(status, orgCode, now);
                }
            }    
        }
        
        if (!msgList.isEmpty()) {
                msgs = msgList.toArray(new String[0]);
            }
        return msgs;
    }
}
